home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / gtlayout-source.lha / LTP_LevelImage.c < prev    next >
C/C++ Source or Header  |  1996-10-03  |  11KB  |  466 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1996 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. #ifdef DO_LEVEL_KIND
  15.  
  16.  
  17. /*****************************************************************************/
  18.  
  19.  
  20. STATIC VOID
  21. DrawLevelImageLeft(struct RastPort *RPort,UWORD *Pens,LevelImageInfo *Level,struct Image *Image,LONG Left,LONG Top,LONG Width,LONG Height,LONG OffsetX,LONG OffsetY)
  22. {
  23.     LONG    BorderTop    = Level->KnobTop,
  24.             BorderLeft    = Level->KnobWidth;
  25.  
  26.     Left    += OffsetX;
  27.     Top        += OffsetY;
  28.  
  29.     if(Width > 0)
  30.     {
  31.         LTP_SetAPen(RPort,Pens[SHADOWPEN]);
  32.         LTP_DrawLine(RPort,Left,Top,Left,Top + Height - 1);
  33.  
  34.         if(Width > 1)
  35.         {
  36.             LTP_DrawLine(RPort,Left + 1,Top,Left + 1,Top + Height - 2);
  37.             LTP_SetAPen(RPort,Pens[SHINEPEN]);
  38.  
  39.             WritePixel(RPort,Left + 1,Top + Height - 1);
  40.  
  41.             if(Width > 2)
  42.             {
  43.                 LTP_DrawLine(RPort,Left + 2,Top + Height - 1,Left + Width - 1,Top + Height - 1);
  44.  
  45.                 LTP_SetAPen(RPort,Pens[SHADOWPEN]);
  46.                 LTP_DrawLine(RPort,Left + 2,Top,Left + Width - 1,Top);
  47.  
  48.                 LTP_SetAPen(RPort,Pens[FILLPEN]);
  49.                 RectFill(RPort,Left + 2,Top + 1,Left + Width - 1,Top + Height - 2);
  50.             }
  51.         }
  52.  
  53.         EraseRect(RPort,Left,Top - BorderTop,Left + Width - 1,Top - 1);
  54.         LTP_EraseBox(RPort,Left,Top + Height,Width,BorderTop);
  55.         EraseRect(RPort,Left - BorderLeft,Top - BorderTop,Left - 1,Top + Height + BorderTop - 1);
  56.     }
  57.     else
  58.     {
  59.         if(Level->Position < BorderLeft && Level->Position > 0)
  60.         {
  61.             Left    = Image->LeftEdge + OffsetX;
  62.             Width    = Level->Position;
  63.  
  64.             EraseRect(RPort,Left,Top - BorderTop,Left + Width - 1,Top + Height + BorderTop - 1);
  65.         }
  66.     }
  67. }
  68.  
  69.  
  70. /*****************************************************************************/
  71.  
  72.  
  73. STATIC VOID
  74. DrawLevelImageRight(struct RastPort *RPort,UWORD *Pens,LevelImageInfo *Level,struct Image *Image,LONG Left,LONG Top,LONG Width,LONG Height,LONG OffsetX,LONG OffsetY)
  75. {
  76.     LONG    BorderTop    = Level->KnobTop,
  77.             BorderLeft    = Level->KnobWidth;
  78.  
  79.     Left    += OffsetX;
  80.     Top        += OffsetY;
  81.  
  82.     if(Width > 0)
  83.     {
  84.         LTP_SetAPen(RPort,Pens[SHINEPEN]);
  85.  
  86.         LTP_DrawLine(RPort,Left + Width - 1,Top,Left + Width - 1,Top + Height - 1);
  87.  
  88.         if(Width > 1)
  89.         {
  90.             LTP_DrawLine(RPort,Left + Width - 2,Top + 1,Left + Width - 2,Top + Height - 1);
  91.             LTP_SetAPen(RPort,Pens[SHADOWPEN]);
  92.  
  93.             WritePixel(RPort,Left + Width - 2,Top);
  94.  
  95.             if(Width > 2)
  96.             {
  97.                 LTP_DrawLine(RPort,Left,Top,Left + Width - 3,Top);
  98.  
  99.                 LTP_SetAPen(RPort,Pens[SHINEPEN]);
  100.                 LTP_DrawLine(RPort,Left,Top + Height - 1,Left + Width - 3,Top + Height - 1);
  101.  
  102.                 LTP_SetAPen(RPort,Pens[BACKGROUNDPEN]);
  103.                 RectFill(RPort,Left,Top + 1,Left + Width - 3,Top + Height - 2);
  104.             }
  105.         }
  106.  
  107.         EraseRect(RPort,Left,Top - BorderTop,Left + Width - 1,Top - 1);
  108.         LTP_EraseBox(RPort,Left,Top + Height,Width,BorderTop);
  109.         EraseRect(RPort,Left + Width,Top - BorderTop,Left + Width + BorderLeft - 1,Top + Height + BorderTop - 1);
  110.     }
  111.     else
  112.     {
  113.         Width = Image->Width - (Level->Position + 2 * BorderLeft);
  114.  
  115.         if(Width > 0)
  116.         {
  117.             Left = Image->LeftEdge + OffsetX + 2 * BorderLeft + Level->Position;
  118.  
  119.             EraseRect(RPort,Left,Top - BorderTop,Left + Width - 1,Top + Height + BorderTop - 1);
  120.         }
  121.     }
  122. }
  123.  
  124.  
  125. /*****************************************************************************/
  126.  
  127.  
  128. STATIC VOID
  129. DrawLevelImageComplete(struct Image *Image,struct RastPort *RPort,UWORD *Pens,LevelImageInfo *Level,LONG OffsetX,LONG OffsetY,BOOL Selected)
  130. {
  131.     LONG    BorderTop    = Level->KnobTop,
  132.             BorderLeft    = Level->KnobWidth,
  133.             Left,Top,
  134.             Width,Height;
  135.     LONG    Position;
  136.  
  137.     Left    = Image->LeftEdge + BorderLeft;
  138.     Top        = Image->TopEdge + BorderTop;
  139.     Width    = Image->Width - 2 * BorderLeft;
  140.     Height    = Image->Height - 2 * BorderTop;
  141.  
  142.     Position = Level->Position + Left;
  143.  
  144.     DrawLevelImageLeft(RPort,Pens,Level,Image,Left,Top,Position - BorderLeft - Left,Height,OffsetX,OffsetY);
  145.     DrawLevelImageRight(RPort,Pens,Level,Image,Position + BorderLeft,Top,Left + Width - (Position + BorderLeft),Height,OffsetX,OffsetY);
  146.  
  147.     BltBitMapRastPort(Level->Knob[Selected ? 1: 0],0,0,RPort,Left + OffsetX + Level->Position - Level->KnobWidth,Image->TopEdge + OffsetY,Level->KnobWidth * 2,Image->Height,0xC0);
  148. }
  149.  
  150.  
  151. /*****************************************************************************/
  152.  
  153.  
  154. STATIC ULONG
  155. LevelClassDraw(struct Image *Image,struct impDraw *DrawMsg,LevelImageInfo *Level)
  156. {
  157.     struct RastPort *RPort = DrawMsg->imp_RPort;
  158.  
  159.         // It doesn't work reliably under v2.04 without these
  160.  
  161.     if(!V39)
  162.         LTP_ResetRenderInfo(RPort);
  163.  
  164.     DrawLevelImageComplete(Image,RPort,Level->Pens,Level,DrawMsg->imp_Offset.X,DrawMsg->imp_Offset.Y,DrawMsg->imp_State == IDS_SELECTED);
  165.  
  166.     if(DrawMsg->imp_State == IDS_DISABLED)
  167.         LTP_GhostBox(RPort,Image->LeftEdge + DrawMsg->imp_Offset.X,Image->TopEdge + DrawMsg->imp_Offset.Y,Image->Width,Image->Height,Level->Pens[SHADOWPEN]);
  168.  
  169.     return(TRUE);
  170. }
  171.  
  172.  
  173. /*****************************************************************************/
  174.  
  175.  
  176. STATIC VOID
  177. LevelClassSet(Class *class,struct Image *Image,struct opSet *SetMsg)
  178. {
  179.     LevelImageInfo    *Level = (LevelImageInfo *)INST_DATA(class,Image);
  180.     struct TagItem    *Item,*List,*PositionItem = NULL;
  181.     LONG             Width = Image->Width - 2 * Level->KnobWidth;
  182.  
  183.     List = SetMsg->ops_AttrList;
  184.  
  185.     while(Item = NextTagItem(&List))
  186.     {
  187.         switch(Item->ti_Tag)
  188.         {
  189.             case LVIA_Current:
  190.                 Level->Current = Item->ti_Data;
  191.                 break;
  192.  
  193.             case LVIA_Max:
  194.                 Level->Max = Item->ti_Data;
  195.                 break;
  196.  
  197.             case LVIA_Position:
  198.                 PositionItem = Item;
  199.                 break;
  200.         }
  201.     }
  202.  
  203.     if(PositionItem)
  204.     {
  205.         LONG Position = (LONG)PositionItem->ti_Data;
  206.  
  207.         if(Position < 0 || !Level->Max)
  208.             Position = 0;
  209.         else
  210.         {
  211.             if(Position > Width)
  212.                 Position = Width;
  213.         }
  214.  
  215.         Level->Position = Position;
  216.     }
  217.     else
  218.     {
  219.         if(Level->Max)
  220.             Level->Position = (Width * Level->Current) / Level->Max;
  221.         else
  222.             Level->Position = 0;
  223.     }
  224. }
  225.  
  226.  
  227. /*****************************************************************************/
  228.  
  229.  
  230. STATIC BOOL
  231. LevelClassGet(Class *class,struct Image *Image,struct opGet *GetMsg)
  232. {
  233.     LevelImageInfo *Level = (LevelImageInfo *)INST_DATA(class,Image);
  234.  
  235.     switch(GetMsg->opg_AttrID)
  236.     {
  237.         case LVIA_Current:
  238.             *GetMsg->opg_Storage = Level->Current;
  239.             return(TRUE);
  240.  
  241.         case LVIA_Max:
  242.             *GetMsg->opg_Storage = Level->Max;
  243.             return(TRUE);
  244.  
  245.         case LVIA_Position:
  246.             *GetMsg->opg_Storage = Level->Position;
  247.             return(TRUE);
  248.  
  249.         case LVIA_KnobWidth:
  250.             *GetMsg->opg_Storage = Level->KnobWidth;
  251.             return(TRUE);
  252.  
  253.         case IA_SupportsDisable:
  254.             *GetMsg->opg_Storage = TRUE;
  255.             return(TRUE);
  256.     }
  257.  
  258.     return(FALSE);
  259. }
  260.  
  261.  
  262. /*****************************************************************************/
  263.  
  264.  
  265. STATIC ULONG
  266. LevelClassNew(Class *class,Object *object,struct opSet *SetMsg)
  267. {
  268.     LONG             Width        = 0,
  269.                      Height     = 0;
  270.     LONG             FontWidth    = 0;
  271.     LONG             Current    = 0,
  272.                      Max        = 0;
  273.     struct DrawInfo *DrawInfo    = NULL;
  274.     struct Screen    *Screen        = NULL;
  275.     struct TagItem    *List,
  276.                     *Item;
  277.  
  278.     List = SetMsg->ops_AttrList;
  279.  
  280.     while(Item = NextTagItem(&List))
  281.     {
  282.         switch(Item->ti_Tag)
  283.         {
  284.             case LVIA_Current:
  285.                 Current = (LONG)Item->ti_Data;
  286.                 break;
  287.  
  288.             case LVIA_Max:
  289.                 Max = (LONG)Item->ti_Data;
  290.                 break;
  291.  
  292.             case LVIA_DrawInfo:
  293.                 DrawInfo = (struct DrawInfo *)Item->ti_Data;
  294.                 break;
  295.  
  296.             case LVIA_FontWidth:
  297.                 FontWidth = Item->ti_Data;
  298.                 break;
  299.  
  300.             case LVIA_Screen:
  301.                 Screen = (struct Screen *)Item->ti_Data;
  302.                 break;
  303.  
  304.             case IA_Width:
  305.                 Width = Item->ti_Data;
  306.                 break;
  307.  
  308.             case IA_Height:
  309.                 Height = Item->ti_Data;
  310.                 break;
  311.         }
  312.     }
  313.  
  314.     if(Width && Height >= 4 && DrawInfo && Screen)
  315.     {
  316.         struct Image *Image;
  317.  
  318.         if(Image = (struct Image *)DoSuperMethodA(class,object,(Msg)SetMsg))
  319.         {
  320.             struct RastPort     RastPort;
  321.             struct RastPort    *RPort;
  322.             LevelImageInfo    *Level = (LevelImageInfo *)INST_DATA(class,Image);
  323.             LONG             QuarterWidth,
  324.                              KnobWidth,
  325.                              LevelHeight,
  326.                              i;
  327.             LONG             Depth;
  328.             struct BitMap    *Friend;
  329.             LONG             Shine,Shadow,Back,Fill;
  330.             UWORD            *Pens;
  331.  
  332.             memset(Level,0,sizeof(LevelImageInfo));
  333.  
  334.             QuarterWidth    = (FontWidth + 3) / 4,
  335.             KnobWidth        = 3 * QuarterWidth,
  336.             LevelHeight        = 2 + (2 * QuarterWidth * DrawInfo->dri_Resolution.X) / DrawInfo->dri_Resolution.Y;
  337.  
  338.             if(LevelHeight >= Height)
  339.                 LevelHeight = Height / 4;
  340.  
  341.             if(LevelHeight < 2)
  342.             {
  343.                 if(Height > 2)
  344.                     LevelHeight = 2;
  345.                 else
  346.                     LevelHeight = Height;
  347.             }
  348.  
  349.             Level->KnobWidth    = KnobWidth;
  350.             Level->KnobTop        = (Height - LevelHeight) / 2;
  351.             Level->LevelHeight    = LevelHeight;
  352.             Level->Max            = Max;
  353.             Level->Current        = Current;
  354.             Level->Pens            = DrawInfo->dri_Pens;
  355.  
  356.             if(Max)
  357.                 Level->Position = ((Width - 2 * KnobWidth) * Current) / Max;
  358.             else
  359.                 Level->Position = 0;
  360.  
  361.             Friend = Screen->RastPort.BitMap;
  362.  
  363.             Depth = LTP_GetDepth(Friend);
  364.  
  365.             Width = Level->KnobWidth * 2;
  366.  
  367.             for(i = 0 ; i < 2 ; i++)
  368.             {
  369.                 if(!(Level->Knob[i] = LTP_CreateBitMap(Width,Height,Depth,Friend,FALSE)))
  370.                 {
  371.                     CoerceMethod(class,object,OM_DISPOSE);
  372.  
  373.                     return(NULL);
  374.                 }
  375.             }
  376.  
  377.             InitRastPort(RPort = &RastPort);
  378.  
  379.             Pens = Level->Pens;
  380.  
  381.             Back = Pens[BACKGROUNDPEN];
  382.  
  383.             for(i = 0 ; i < 2 ; i++)
  384.             {
  385.                 RPort->BitMap = Level->Knob[i];
  386.  
  387.                 Fill    = Pens[i ? FILLPEN : BACKGROUNDPEN];
  388.                 Shine    = Pens[SHINEPEN];
  389.                 Shadow    = Pens[SHADOWPEN];
  390.  
  391.                 SetRast(RPort,Fill);
  392.  
  393.                 LTP_RenderBevel(RPort,Pens,0,0,Width,Height,FALSE,2);
  394.  
  395.                 if(Fill == Shine || Fill == Shadow)
  396.                     Shine = Shadow = Back;
  397.  
  398.                 LTP_SetAPen(RPort,Shine);
  399.                 LTP_DrawLine(RPort,Width / 2,2,Width / 2,Height - 3);
  400.  
  401.                 LTP_SetAPen(RPort,Shadow);
  402.                 LTP_DrawLine(RPort,Width / 2 - 1,2,Width / 2 - 1,Height - 3);
  403.             }
  404.  
  405.             return((ULONG)Image);
  406.         }
  407.     }
  408.  
  409.     return(NULL);
  410. }
  411.  
  412.  
  413. STATIC VOID
  414. LevelClassDispose(Class *class,Object *object)
  415. {
  416.     LevelImageInfo    *Level = (LevelImageInfo *)INST_DATA(class,object);
  417.     LONG             i;
  418.  
  419.     for(i = 0 ; i < 2 ; i++)
  420.     {
  421.         if(Level->Knob[i])
  422.         {
  423.             WaitBlit();
  424.  
  425.             break;
  426.         }
  427.     }
  428.  
  429.     for(i = 0 ; i < 2 ; i++)
  430.         LTP_DeleteBitMap(Level->Knob[i],FALSE);
  431. }
  432.  
  433. /*****************************************************************************/
  434.  
  435.  
  436. ULONG SAVE_DS ASM
  437. LTP_LevelClassDispatcher(REG(a0) Class *class,REG(a2) Object *object,REG(a1) Msg msg)
  438. {
  439.     switch(msg->MethodID)
  440.     {
  441.         case IM_DRAW:
  442.             return(LevelClassDraw((struct Image *)object,(struct impDraw *)msg,(LevelImageInfo *)INST_DATA(class,object)));
  443.  
  444.         case OM_SET:
  445.             LevelClassSet(class,(struct Image *)object,(struct opSet *)msg);
  446.             break;
  447.  
  448.         case OM_GET:
  449.             if(LevelClassGet(class,(struct Image *)object,(struct opGet *)msg))
  450.                 return(TRUE);
  451.  
  452.             break;
  453.  
  454.         case OM_NEW:
  455.             return(LevelClassNew(class,object,(struct opSet *)msg));
  456.  
  457.         case OM_DISPOSE:
  458.             LevelClassDispose(class,object);
  459.  
  460.             // Falls down through to the default case...
  461.     }
  462.  
  463.     return(DoSuperMethodA(class,object,msg));
  464. }
  465. #endif    /* DO_LEVEL_KIND */
  466.